package com.yifeng.repo.storage.elasticsearch;

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.cluster.metadata.MappingMetadata;

import java.util.Map;

/**
 * Created by daibing on 2021/5/18.
 */
@Slf4j
public class ElasticSearchIndexWorker {
    private final RestHighLevelClient esClient;


    public ElasticSearchIndexWorker(ElasticSearchClient client) {
        // 默认仅支持单集群
        this.esClient = client.getClient();
    }

    public String create(String indexName, Map<String, Object> settings, Map<String, Object> mappings, Map<String, Object> aliases) {
        CreateIndexRequest request = new CreateIndexRequest(indexName);
        try {
            if (settings != null && settings.size() > 0) {
                request.settings(settings);
            }
            if (mappings != null && mappings.size() > 0) {
                request.mapping(mappings);
            }
            if (aliases != null && aliases.size() > 0) {
                request.aliases(aliases);
            }
            CreateIndexResponse response = esClient.indices().create(request, RequestOptions.DEFAULT);
            boolean acknowledged = response.isAcknowledged();
            if (acknowledged) {
                return indexName;
            }
            throw new RuntimeException("create index " + indexName + " failed without acknowledged.");
        } catch (Throwable t) {
            log.warn("create index failed: indexName={}, error=", indexName, t);
            throw new RuntimeException("create index " + indexName + " failed, error: ", t);
        }
    }

    public String remove(String indexName) {
        DeleteIndexRequest request = new DeleteIndexRequest(indexName);
        try {
            AcknowledgedResponse response = esClient.indices().delete(request, RequestOptions.DEFAULT);
            boolean acknowledged = response.isAcknowledged();
            if (acknowledged) {
                return indexName;
            }
            throw new RuntimeException("remove index " + indexName + " failed without acknowledged.");
        } catch (Throwable t) {
            log.warn("remove index failed: indexName={}, error=", indexName, t);
            throw new RuntimeException("remove index " + indexName + " failed, error: ", t);
        }
    }

    public boolean contain(String indexName) {
        GetIndexRequest request = new GetIndexRequest(indexName);
        try {
            return esClient.indices().exists(request, RequestOptions.DEFAULT);
        } catch (Throwable t) {
            log.warn("contain index failed: indexName={}, error=", indexName, t);
            throw new RuntimeException("contain index " + indexName + " failed, error: ", t);
        }
    }

    public Map<String, MappingMetadata> get(String indexName) {
        GetIndexRequest request = new GetIndexRequest(indexName);
        try {
            GetIndexResponse response = esClient.indices().get(request, RequestOptions.DEFAULT);
            return response.getMappings();
        } catch (Throwable t) {
            log.warn("get index failed: indexName={}, error=", indexName, t);
            throw new RuntimeException("get index " + indexName + " failed, error: ", t);
        }
    }

    public String alias(String indexName, String aliasName) {
        IndicesAliasesRequest request = new IndicesAliasesRequest();
        try {
            request.addAliasAction(new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.ADD)
                    .index(indexName)
                    .alias(aliasName));
            AcknowledgedResponse response = esClient.indices().updateAliases(request, RequestOptions.DEFAULT);
            boolean acknowledged = response.isAcknowledged();
            if (acknowledged) {
                return indexName;
            }
            throw new RuntimeException("alias index " + indexName + " to " + aliasName + " failed without acknowledged.");
        } catch (Throwable t) {
            log.warn("alias index failed: indexName={}, aliasName={}, error=", indexName, aliasName, t);
            throw new RuntimeException("alias index " + indexName + " to " + aliasName + " failed, error: ", t);
        }
    }
}
